<?php
namespace App\Lib\Request;

//继承和接口不能随便改..
class ResultObject extends \stdClass implements \ArrayAccess
{
    protected $__index = 0;
    protected $__data = [];

    public function __construct($data, $name = null) {
        $this->__index = 0;
        if (is_array($data) || is_object($data)) {
            foreach ($data as $key => $value) {
                if (is_object($value)) {
                    if (!$this->is_object_empty($value)) {
                        $value = new self($value, $key);
                    }
                }
                if (is_array($value)) {
                    $value = new self($value, $key);
                }
                $this->$key = $value;
                $this->__data[$key] = $value;
            }
        } else {
            if ($name !== null) {
                $this->$name = $data;
                $this->__data[$name] = $data;
            } else {
                $this->__data = $data;
            }
        }
    }

    public function __toString()
    {
        return  is_string($this->__data) ? $this->__data : json_encode($this->toArray());
    }

    private function convertToArray($arr)
    {
        if (is_string($arr)) {
            return $arr;
        }
        if ($this->is_object_empty($arr)) {
            return $arr;
        }
        if ($arr instanceof \stdClass) {
            $arr = json_decode(json_encode($arr), true);
        }
        foreach ($arr as $k => $v) {
            if ($v instanceof ResultObject) {
                $arr[$k] = $v->toArray();
            } elseif (is_array($v)) {
                if (empty($v)) {
                    $arr[$k] = [];
                } else {
                    foreach ($v as $_k => $_v) {
                        $arr[$k][$_k] = $this->convertToArray($_v);
                    }
                }
            } elseif($v instanceof \stdClass) {
                if (!$this->is_object_empty($v)) {
                    $arr[$k] = json_decode(json_encode($v), true);
                } else {
                    $arr[$k] = new \stdClass();
                }
            } else {
                $arr[$k] = $v;
            }
        }
        return $arr;
    }

    /**
     * {
    "Success": false,
    "Code": "500",
    "Message": "string代理超时"
    }
     */
    public function isOk()
    {
        return (boolean)$this->__data['Success'] != false;
    }

    public function getErrorMessage()
    {
        return $this->__data['Message'];
    }

    public function getErrorCode()
    {
        return $this->__data['Code'];
    }

    public function toArray()
    {
        return $this->convertToArray($this->__data);
    }

    public function pop()
    {
        return array_pop($this->__data);
    }


    public function shift()
    {
        return array_shift($this->__data);
    }

    public function getColumn($key)
    {
        return array_column($this->__data, $key);
    }

    public function current()
    {
        return $this->__data[$this->__index];
    }

    public function next()
    {
        return $this->__index ++;
    }

    public function key()
    {
        return $this->__index;
    }

    public function valid()
    {
        return isset($this->__data[$this->__index]);
    }

    public function rewind()
    {
       $this->__index = 0;
    }

    public function offsetExists($offset)
    {
        return isset($this->__data[$offset]);
    }

    public function offsetGet($offset)
    {
        try {
           return is_numeric($offset) ? $this->__data[$offset]: $this->$offset;
        } catch (\Exception $exception) {
           return $this->__data[$offset];
        }
    }

    public function offsetSet($offset, $value)
    {
        $this->__data[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        unset($this->__data[$offset]);
    }

    public function empty()
    {
        return empty($this->__data);
    }

    private function is_object_empty($item) {
        return empty(json_decode(json_encode($item), true));
    }
}